package com.ruoyi.system.service.impl;

import com.alibaba.fastjson.JSON;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.enums.RetResponse;
import com.ruoyi.common.enums.RetResult;
import com.ruoyi.common.utils.*;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.mapper.*;
import com.ruoyi.system.service.IQrcodeService;
import com.ruoyi.web.controller.config.WxConfig;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 用户 业务层处理
 *
 * @author ruoyi
 */
@Service
public class QrcodeServiceImpl implements IQrcodeService {
    private static Logger logger = LoggerFactory.getLogger("sys-wx");


    // 角色标识 -> 扫一扫重定向到详情页面
    public static final String DETAIL = "detail";

    // 角色标识 -> 材料员
    public static final String MATER = "mater";

    // 角色标识 -> 运输车
    public static final String TRUCK = "truck";

    // 角色标识 -> 首次未注册
    public static final String NO = "no";

    @Autowired
    private QrcodeMapper qrcodeMapper;

    @Autowired
    private WxInfoMapper wxInfoMapper;

    @Autowired
    private WxMaterMapper wxMaterMapper;

    @Autowired
    private WxTokenMapper wxTokenMapper;

    @Override
    public RetResult<Object> queryUserPerm(WxInfo wxInfo) {
        // Case1 扫一扫重定向
        if (wxInfo.getOpenId().contains("id=")) {
            String id = wxInfo.getOpenId().replace("id=", "");
            Driver drivers = qrcodeMapper.queryDriverDetail(id);
            drivers.setCode(DETAIL);
            return RetResponse.makeOKRsp(drivers);
        }

        // Case2 判断用户权限
        List<WxInfo> wxInfos = wxInfoMapper.selectWxInfoByOpenId(wxInfo);
        if (StringUtils.isNotEmpty(wxInfos)) {
            // 判断是材料员还是运输车
            // 获取所有材料员的信息
            WxMater wxMater = new WxMater();
            wxMater.setMaterPhone(wxInfos.get(0).getPhone());
            List<WxMater> wxMaters = wxMaterMapper.selectWxMaterList(wxMater);
            if (StringUtils.isNotEmpty(wxMaters)) {
                // 材料员
                wxMaters.get(0).setCode(MATER);
                return RetResponse.makeOKRsp(wxMaters.get(0));
            } else {
                // 运输车
                wxInfos.get(0).setCode(TRUCK);
                return RetResponse.makeOKRsp(wxInfos.get(0));
            }
        } else {
            // 首次注册
            WxInfo info = new WxInfo();
            info.setCode(NO);
            return RetResponse.makeOKRsp(info);
        }
    }

    @Override
    public List<Driver> queryDriverByOpenId(Driver driver) {
        return qrcodeMapper.queryDriverByOpenId(driver);
    }

    @Override
    @Transactional
    public RetResult<Object> queryTrunkNum(DriverRecord driverrecord) {
        logger.info("查询运输车统计次数入参:" + driverrecord);
        int dayNum = qrcodeMapper.queryTrunkDayNum(driverrecord);
        int monNum = qrcodeMapper.queryTrunkMonNum(driverrecord);
        int accNum = qrcodeMapper.queryTrunkAccNum(driverrecord);

        logger.info(driverrecord.getOpenId() + "运输车日统计次数为:" + dayNum);
        logger.info(driverrecord.getOpenId() + "运输车月统计次数为:" + monNum);
        logger.info(driverrecord.getOpenId() + "运输车累计统计次数为:" + accNum);

        RecordCount recordCount = new RecordCount();
        recordCount.setDayNum(dayNum);
        recordCount.setMonNum(monNum);
        recordCount.setAccNum(accNum);
        return RetResponse.makeOKRsp(recordCount);
    }

    @Override
    public RetResult<Object> queryMaterPerms(WxMater wxMater) {
        logger.info("查询材料员所负责项目列表:" + wxMater.getMaterPhone());

        List<SysDept> sysDepts = wxMaterMapper.selectDeptsByMaterPhone(wxMater.getMaterPhone());
        return RetResponse.makeOKRsp(sysDepts);
    }

    @Override
    @Transactional
    public RetResult<Object> queryMaterNum(DriverRecord driverrecord) {
        logger.info("查询材料员统计次数入参:" + driverrecord);
        int dayNum = qrcodeMapper.queryMaterDayNum(driverrecord);
        int monNum = qrcodeMapper.queryMaterMonNum(driverrecord);
        int accNum = qrcodeMapper.queryMaterAccNum(driverrecord);

        logger.info(driverrecord.getMopenId() + "材料员日统计次数为:" + dayNum);
        logger.info(driverrecord.getMopenId() + "材料员月统计次数为:" + monNum);
        logger.info(driverrecord.getMopenId() + "材料员累计统计次数为:" + accNum);

        RecordCount recordCount = new RecordCount();
        recordCount.setDayNum(dayNum);
        recordCount.setMonNum(monNum);
        recordCount.setAccNum(accNum);
        return RetResponse.makeOKRsp(recordCount);
    }

    @Transactional
    @Override
    public String generateQrcodePath(Driver driver,String resourceProfile) throws Exception{

        try {
            // Step1 新增运输车提交表单信息
            driver.setDayTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            qrcodeMapper.insertDriver(driver);

            // Step2 生成二维码到指定目录
            // 二维码内容
            String qrcodeContent = WxConfig.SERVER_BASE_URL + "/qrcode/queryDriverDetail?id=" + driver.getId();
            String fileName = QRCodeUtil.encode(qrcodeContent, resourceProfile+Constants.LOGO_FILE, new File(RuoYiConfig.getProfile()).getAbsolutePath(), true);

            // Step3 对指定目录进行资源映射路径
            return WxConfig.SERVER_BASE_URL + Constants.RESOURCE_PREFIX + "/" + fileName;
        } catch (Exception e) {
            e.printStackTrace();
            return "fail";
        }
    }

    @Override
    public Driver queryDriverDetailInfo(Driver driver) {


        // Step1 查询运输车提交表单信息
        Driver drivers = qrcodeMapper.queryDriverDetail(driver.getId());

        // Step2 根据材料员姓名查询上次审批的工作内容、备注
        DriverRecord driverRecord = new DriverRecord();
        driverRecord.setMaterName(driver.getMaterName());
        driverRecord.setDeptId(drivers.getDeptId());
        List<DriverRecord> driverRecords = qrcodeMapper.queryDriverRecord(driverRecord);
        if (StringUtils.isNotEmpty(driverRecords)) {
            drivers.setWorkContent(driverRecords.get(0).getWorkContent());
            drivers.setRemark(driverRecords.get(0).getRemark());
            drivers.setClockTime(driverRecords.get(0).getCreateTimes());
        }
        return drivers;
    }

    @Override
    @Transactional
    public String insertWxInfo(WxInfo wxInfo) {
        // 1、首次注册   status 0          项目id,手机号 唯一校验
        // 2、切换项目   status 3          根据项目id,手机号先查询,有值删除,无值新增
        // 3、A切换B后在切换A  status 3    根据项目id,手机号先查询,有值删除,无值新增
        if(wxInfo.getStatus().equals("0")){
            // Case1、首次注册   status 0
            List<WxInfo> wxInfos = wxInfoMapper.checkWxInfoListUnique(wxInfo);
            if (StringUtils.isNotEmpty(wxInfos)) {
                // 存在重复数据
                return "repeat";
            }else{
                wxInfoMapper.insertWxInfo(wxInfo);
            }
        }else{
            // Case2&3、 status 3
            List<WxInfo> infos = wxInfoMapper.checkWxInfoListUnique(wxInfo);
            if(StringUtils.isNotEmpty(infos)){
                wxInfoMapper.deleteWxInfoById(infos.get(0).getId());
            }
            wxInfo.setStatus("0");
            wxInfoMapper.insertWxInfo(wxInfo);
        }
        return "success";
    }

    @Transactional
    @Override
    public String approvedRecord(DriverRecord driverrecord, long intervalTime) {
        try {
            // Step1 校验生成同一二维码生成时间间隔
            String nowTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
            List<DriverRecord> records = qrcodeMapper.queryDriverRecordByOpenId(driverrecord);

            String res = HttpClientUtils.get(WxConfig.TOKEN_URL,new HashMap<>());
            String token = com.alibaba.fastjson.JSONObject.parseObject(res).getString("token");
            logger.info("发送消息模板token：" + token);
            if (StringUtils.isNotEmpty(records)) {
                logger.info("非首次打卡,入参:" + records);

                String createTime = records.get(0).getCreateTimes();

                logger.info(driverrecord.getDriverName() + "当前审批时间为：" + nowTime);
                logger.info(driverrecord.getDriverName() + "最新审批时间为：" + createTime);

                long mDiff = DateUtils.dateDiff(createTime, nowTime, "yyyy-MM-dd HH:mm:ss");

                logger.info(driverrecord.getDriverName() + "审批时间差为：" + mDiff);

                if (mDiff >= intervalTime) {
                    logger.info(driverrecord.getDriverName() + "审批时间差大于时间间隔");

                    driverrecord.setNum(String.valueOf(Integer.valueOf(records.get(0).getNum()) + 1)); // 设置
                    driverrecord.setCreateTimes(nowTime);
                    driverrecord.setLastTime(createTime);
                    driverrecord.setIntervalSecond(DateUtils.getTime(createTime, nowTime));

                    // Step2 新增审批记录表
                    logger.info("新增审批记录表入参为:" + driverrecord);
                    qrcodeMapper.insertRecord(driverrecord);

                    // Step4 发送模板消息
                    logger.info("首次发送模板消息getAccessToken" + token);
                    sendMsg(driverrecord,token);
                    return "success";
                } else {
                    logger.info(driverrecord.getDriverName() + "审批时间差小于时间间隔");
                    return "fail";
                }
            } else {
                driverrecord.setNum("1");
                driverrecord.setCreateTimes(nowTime);
                driverrecord.setLastTime("");
                // 获取当前月累计打卡次数
                logger.info("新增审批记录表入参为:" + driverrecord);
                qrcodeMapper.insertRecord(driverrecord);

                logger.info("非首次发送模板消息getAccessToken" + token);
                sendMsg(driverrecord,token);
                return "success";
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.info("材料员详情界面 -> 审批通过报错信息" + e.getMessage());
            return "fail";
        }
    }

    @Override
    @Transactional
    public RetResult<String> switchDept(WxMater wxMater) {

        // Step1 根据手机号获取材料员的部门ID
        try {
            WxMater mater = wxMaterMapper.queryMaterByPhone(wxMater);

            // Step2 根据权限部门ID和材料员原部门ID更新权限表
            Map<String, Object> map = new HashMap<>();
            map.put("deptId", mater.getDeptId());
            map.put("assDeptId", wxMater.getDeptId());
            wxMaterMapper.updatePermByDeptId(map);

            // Step3 更新材料员表
            wxMaterMapper.updateMaterByPhone(wxMater);
            return RetResponse.makeOKRsp("success");
        } catch (Exception e) {
            return RetResponse.makeErrRsp("fail");
        }
    }


    private void sendMsg(@RequestBody DriverRecord driverrecord,String accessToken) throws IOException {
        try {
            String postUrl = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken;
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("touser", driverrecord.getOpenId());   // openid
            jsonObject.put("template_id", "sRKzwxUrHbFmHPxa-xFTBaZHV0TnPqL9isho1Hm5a8s");
            jsonObject.put("url", "http://jp.tsferp.com/wxLogin/code");
            logger.info("发送消息参数touser:" + driverrecord.getOpenId());
            logger.info("发送消息参数accessToken:" + accessToken);


            JSONObject data = new JSONObject();
            JSONObject first = new JSONObject();
            first.put("value", "审批同意");
            first.put("color", "#173177");
            JSONObject keyword1 = new JSONObject();
            keyword1.put("value", driverrecord.getProgramName());
            keyword1.put("color", "#173177");
            JSONObject keyword2 = new JSONObject();
            keyword2.put("value", driverrecord.getDriverName());
            keyword2.put("color", "#173177");
            JSONObject keyword3 = new JSONObject();
            keyword3.put("value", driverrecord.getLicensePlate());
            keyword3.put("color", "#173177");
            JSONObject keyword4 = new JSONObject();
            keyword4.put("value", driverrecord.getNum());
            keyword4.put("color", "#173177");
            JSONObject remark = new JSONObject();
            remark.put("value", "欢迎您的使用!");
            remark.put("color", "#173177");

            data.put("first", first);
            data.put("keyword1", keyword1);
            data.put("keyword2", keyword2);
            data.put("keyword3", keyword3);
            data.put("keyword4", keyword4);
            data.put("remark", remark);

            jsonObject.put("data", data);
            logger.info("发送消息参数jsonObject:" + jsonObject);

            String string = HttpClientUtils.sendPostJsonStr(postUrl, jsonObject.toString());
            com.alibaba.fastjson.JSONObject result = JSON.parseObject(string);
            int errcode = result.getIntValue("errcode");
            logger.info("发送消息结果errcode:" + errcode);

            if (errcode == 0) {
                // 发送成功
                logger.info("发送消息结果成功");
            } else {
                // 发送失败
                logger.info("发送消息结果失败");
            }
        }catch (Exception e){
            logger.info("发送消息结果失败e:"+e);
        }

    }
}
